package br.com.main.server;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import br.com.main.client.system.botoes.Denuncia;
import br.com.main.client.system.botoes.Morador;
import br.com.main.client.system.botoes.Notificacao;
import br.com.main.client.system.botoes.Reserva;

public class ConnectionFactory {

	private Connection con;
	private PreparedStatement comando;

	public ConnectionFactory() {
		novaOracle();
	}

	private void novaOracle() {
		/*
		 * String serverName = "oracle11g.cin.ufpe.br"; String portNumber =
		 * "1521"; String sid = "Instance01"; String url = "jdbc:oracle:thin:@"
		 * + serverName + ":" + portNumber + ":" + sid; String user =
		 * "g132if976_eq05"; String password = "enkyeugays3";
		 */

		String serverName = "localhost";
		String portNumber = "1521";
		String sid = "xe";
		String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":"
				+ sid;
		String user = Constans.usuario;
		String password = Constans.senha;

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			con = DriverManager.getConnection(url, user, password);
			System.out.println("Conexao feita");
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public String consulta(String sql) {
		String r = "False";
		try {
			comando = con.prepareStatement(sql);
			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				r = "True";
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return r;
	}

	public String atualizaMorador(String nome, String cpf, String email,
			String telefone, String data_nasc, String numero, String bloco,
			String andar) {
		String sql;
		sql = "UPDATE Pessoa SET nome = '" + nome + "', email = '" + email
				+ "', telefone = '" + telefone + "', data_nasc = '" + data_nasc +"' WHERE cpf = '" + cpf + "'";
		
		// falta atualizar o moradorapt;
		try {
			comando = con.prepareStatement(sql);
			comando.executeUpdate();
			return "True";
		} catch (SQLException e) {
			e.printStackTrace();
			return "False";
		}

	}

	public String cadastroMorador(String nome, String cpf, String email,
			String telefone, String data_nasc, String numero, String bloco,
			String andar, String cnpj) {
		String sql;
		try {
			sql = "INSERT INTO Pessoa (cpf, nome, login, senha, email, telefone, data_nasc) VALUES (?, ?, ?, ?, ?, ?, ?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, cpf);
			comando.setString(2, nome);
			String login = numero + bloco;
			comando.setString(3, login);
			String senha = "1234";
			comando.setString(4, senha);
			comando.setString(5, email);
			comando.setString(6, telefone);
			comando.setString(7, data_nasc);
			comando.executeUpdate();

			sql = "INSERT INTO Apartamento (numero, bloco, valor, andar, cnpj) VALUES (?, ?, ?, ?, ?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, numero);
			comando.setString(2, bloco);
			comando.setInt(3, 666);
			comando.setString(4, andar);
			comando.setString(5, cnpj);
			comando.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			return "Não cadastrado";
		}

		return "Cadastrado";
	}

	public String cadastroAreaLazer(String nome, String capacidade,
			String tempoMaximo, String cnpj) {
		String sql;
		try {
			sql = "INSERT INTO Area_lazer (id, nome, tempo_max, capacidade,cnpj) VALUES (seq_areaLazer.nextval, ?, ?, ?,?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, nome);
			comando.setString(2, tempoMaximo);
			comando.setString(3, capacidade);
			comando.setString(4, cnpj);
			comando.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			return "Não cadastrado";
		}

		return "Cadastrado";
	}

	public String cadastroDespesa(String descricao, String valor, String data,
			String cnpj, String pago) {
		String sql;
		valor = customFormat(valor);
		try {
			sql = "INSERT INTO Despesas (descricao_despesa, cnpj, valor, data_despesa,pago) VALUES ('"
					+ descricao
					+ "', '"
					+ cnpj
					+ "', "
					+ valor
					+ ", TO_DATE('"
					+ data + "','DD/MM/yyyy'),'" + pago + "')";
			comando = con.prepareStatement(sql);

			comando.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			return "Não cadastrado";
		}

		return "Cadastrado";
	}

	public String logarSindico(String login, String senha, String cnpj) {
		String retorno = "False";
		try {
			String sql = "SELECT * FROM Pessoa P, Condominio C WHERE login = '"
					+ login + "' AND senha = '" + senha + "' AND C.cnpj = '"
					+ cnpj + "' AND P.cpf = C.cpf_sindico";
			comando = con.prepareStatement(sql);

			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				retorno = "True";
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return retorno;
		}

		return retorno;
	}
	public String[] recuperarSenha(String email) {
		
		String[] dadosRecuperado = null;
		try {
			String sql = "Select * from PESSOA where email like '"+email+"'";
			comando = con.prepareStatement(sql);
			
			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				dadosRecuperado = new String[]{resultado.getString("nome"),resultado.getString("login"),
						resultado.getString("senha")};
				
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return dadosRecuperado;
		}
		
		return dadosRecuperado;
	}

	public String logarMorador(String login, String senha, String cnpj) {
		String retorno = "False";
		try {
			String sql = "SELECT * FROM Pessoa P INNER JOIN MoradorApt MA ON P.cpf = MA.cpf_condomino AND MA.cnpj LIKE '"
					+ cnpj
					+ "' WHERE P.login LIKE '"
					+ login
					+ "' AND P.senha LIKE '" + senha + "'";
			comando = con.prepareStatement(sql);

			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				String cpf = resultado.getString(1);
				retorno = cpf;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return retorno;
		}

		return retorno;
	}

	public String[] dadosFormularioCondominio(String cnpj) {
		String[] retorno = null;

		String cep = "";
		String cpfSindico = "";

		try {
			String sql = "select cpf_sindico,cep from CONDOMINIO where CNPJ like '"
					+ cnpj + "' ";
			comando = con.prepareStatement(sql);
			
			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
			
				cpfSindico = resultado.getString("cpf_sindico");
				cep = resultado.getString("cep");
				retorno = new String[] { cpfSindico, cep };

			}
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		
		return retorno;
	}
	public String[] dadosFormularioSindoco(String cnpj) {

		String emailSindico = "";

		String[] dadosCondominio = dadosFormularioCondominio(cnpj);
		String[] retorno = null;
		
		try {
			String sql = "select email from Pessoa where cpf like '"
					+ dadosCondominio[0] + "'";
			comando = con.prepareStatement(sql);
			
			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				emailSindico = resultado.getString("email");
				retorno = new String[] { emailSindico, dadosCondominio[1] };
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return retorno;
		}
		
		return retorno;
	}
	public String[] dadosFormularioMorador(String cpfMorador, String cnpj) {

		String nomeMorador = "";
		String emailMorador = "";
		String telefoneMorador = "";

		String[] dadosSindico = dadosFormularioSindoco(cnpj);
		String[] retorno = null;

		try {
			String sql = "select nome, email, telefone from PESSOA where cpf like '"
					+ cpfMorador + "'";
			comando = con.prepareStatement(sql);

			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				nomeMorador = resultado.getString("nome");
				emailMorador = resultado.getString("email");
				telefoneMorador = resultado.getString("telefone");
				retorno = new String[] { dadosSindico[0], nomeMorador,
						dadosSindico[1], telefoneMorador, emailMorador };

			}
		} catch (SQLException e) {
			e.printStackTrace();
			return retorno;
		}
		
		return retorno;
	}

	public List<String[]> carregarAreaLazer(String cnpj) {
		List<String[]> lazerList = null;
		try {
			lazerList = new ArrayList<String[]>();
			String sql = "select * from AREA_LAZER where CNPJ like '" + cnpj
					+ "'";
			comando = con.prepareStatement(sql);
			ResultSet resultado = comando.executeQuery();
			while (resultado.next()) {
				String[] lazerArray = new String[] {
						resultado.getString("nome"),
						resultado.getString("tempo_max"),
						resultado.getString("capacidade"),
						resultado.getString("id") };
				lazerList.add(lazerArray);

			}
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}

		return lazerList;
	}

	public List<String[]> carregarDespesas(String cnpj) {
		List<String[]> despesasList = null;
		try {
			despesasList = new ArrayList<String[]>();
			String sql = "select * from DESPESAS where CNPJ like '" + cnpj
					+ "'";
			comando = con.prepareStatement(sql);
			ResultSet resultado = comando.executeQuery();
			while (resultado.next()) {
				String[] despesasArray = new String[] {
						customFormat(resultado.getString("valor")),
						resultado.getString("descricao_despesa"),
						resultado.getString("data_despesa"),
						resultado.getString("pago") };
				System.out.println("Aqui");

				System.out.println();
				despesasList.add(despesasArray);

			}
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}

		return despesasList;
	}

	public String cadastrarSindicoCondominio(String cpf, String nome,
			String login, String senha, String email, String telefone,
			String data_nasc, String data_mandato, String cnpj, String cep,
			String estado, String cidade, String bairro, String rua,
			int numero, String complemento) {

		try {
			String sql = "INSERT INTO Pessoa (cpf, nome, login, senha, email, telefone, data_nasc) VALUES (?, ?, ?, ?, ?, ?, ?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, cpf);
			comando.setString(2, nome);
			comando.setString(3, login);
			comando.setString(4, senha);
			comando.setString(5, email);
			comando.setString(6, telefone);
			comando.setString(7, data_nasc);
			comando.executeUpdate();

			sql = "INSERT INTO Sindico (cpf_sindico, data_mandato) VALUES (?, ?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, cpf);
			comando.setString(2, data_mandato);
			comando.executeUpdate();

			sql = "INSERT INTO Condominio (cnpj, nome, cep, estado, bairro, cidade, rua, numero, complemento, cpf_sindico) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
			comando = con.prepareStatement(sql);
			comando.setString(1, cnpj);
			comando.setString(2, "Sistema");
			comando.setString(3, cep);
			comando.setString(4, estado);
			comando.setString(5, bairro);
			comando.setString(6, cidade);
			comando.setString(7, rua);
			comando.setInt(8, numero);
			comando.setString(9, complemento);
			comando.setString(10, cpf);
			comando.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			return "Não cadastrado";
		}
		return "Cadastrado";
	}

	public ArrayList<Morador> carregarMoradores(String cnpj, String cpf_usuario) {
		ArrayList<Morador> retorno = new ArrayList<Morador>();
		
		String sql;
		try {
			sql = "SELECT * FROM Pessoa P, MoradorApt MA WHERE P.cpf != '"+cpf_usuario+"' AND P.cpf = MA.cpf_condomino AND MA.cnpj = '"
					+ cnpj + "'";
			comando = con.prepareStatement(sql);
			ResultSet resultado = comando.executeQuery();

			sql = "SELECT * FROM Apartamento WHERE cnpj = '" + cnpj + "'";
			comando = con.prepareStatement(sql);
			ResultSet resultado2 = comando.executeQuery();
			
			while (resultado.next() && resultado2.next()) {
				String nome = resultado.getString("nome");
				String cpf = resultado.getString("cpf");
				String email = resultado.getString("email");
				String telefone = resultado.getString("telefone");
				String data_nasc = resultado.getString("data_nasc");
				String numero = resultado2.getString("numero");
				String bloco = resultado2.getString("bloco");
				String andar = resultado2.getString("andar");
				Morador e = new Morador(nome, cpf, email, telefone, data_nasc,
						numero, bloco, andar);
				retorno.add(e);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return retorno;
	}

	public String getAlgo(String sql) { // select para retornar apenas 1
		// elemento
		try {
			comando = con.prepareStatement(sql);
			ResultSet resultado = comando.executeQuery();
			if (resultado.next()) {
				return resultado.getString(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return "sem retorno";
	}

	public String[] getSindico(String cpfSindico) throws SQLException {

		String sql = "SELECT p.*, s.DATA_MANDATO, co.* FROM Pessoa p INNER JOIN Sindico s ON  p.CPF = '"
				+ cpfSindico
				+ "' AND s.CPF_SINDICO = p.CPF  INNER JOIN CONDOMINIO co ON co.CPF_SINDICO = p.CPF";
		
		this.comando = this.con.prepareStatement(sql);
		ResultSet resultado = this.comando.executeQuery();

		String[] sindico = new String[17];
		if (resultado.next()) {
			for (int i = 0; i < sindico.length; i++) {
				sindico[i] = resultado.getString(i + 1);
			}
		}
		return sindico;

	}

	public void updateSindico(String[] novosDados, String cpfSindico)
			throws SQLException {
		String sql = "UPDATE Pessoa SET nome = ?, login = ?, email = ?, telefone = ?, data_nasc = ? WHERE cpf = '"
				+ cpfSindico + "'";
		comando = this.con.prepareStatement(sql);
		comando.setString(1, novosDados[0]);
		comando.setString(2, novosDados[1]);
		comando.setString(3, novosDados[2]);
		comando.setString(4, novosDados[3]);
		comando.setString(5, novosDados[4]);

		comando.executeUpdate();

		sql = "UPDATE Sindico SET data_mandato = to_date(?,'DD/MM/YYYY') WHERE cpf_sindico = '"
				+ cpfSindico + "'";
		comando = this.con.prepareStatement(sql);
		comando.setString(1, novosDados[5]);

		comando.executeUpdate();

		sql = "UPDATE Condominio SET nome = ?, cep = ?, estado = ?, cidade = ?, bairro = ?, rua = ?, numero = ?, complemento = ? WHERE cpf_sindico = '"
				+ cpfSindico + "'";
		comando = this.con.prepareStatement(sql);
		String c;
		if (novosDados[13] != null || !novosDados[13].equals("")) {
			c = novosDados[13];
		} else {
			c = " ";
		}
		comando.setString(1, novosDados[6]);
		comando.setString(2, novosDados[7]);
		comando.setString(3, novosDados[8]);
		comando.setString(4, novosDados[9]);
		comando.setString(5, novosDados[10]);
		comando.setString(6, novosDados[11]);
		comando.setInt(7, Integer.parseInt(novosDados[12]));
		comando.setString(8, c);

		comando.executeUpdate();
	}

	public ArrayList<Reserva> listReservas(String cnpj) throws SQLException {
		ArrayList<Reserva> reservas = new ArrayList<Reserva>();

		String sql = "SELECT r.CPF_RESPONSAVEL, p.NOME, al.NOME, r.DATA_RESERVA FROM Reserva r INNER JOIN Pessoa p ON r.CNPJ = '"
				+ cnpj
				+ "' AND p.CPF = r.CPF_RESPONSAVEL INNER JOIN AREA_LAZER al ON r.ID = al.ID";
		this.comando = this.con.prepareStatement(sql);
		ResultSet resultado = comando.executeQuery();

		while (resultado.next()) {
			Reserva res = new Reserva(resultado.getString(1),
					resultado.getString(2), resultado.getString(3),
					resultado.getString(4));
			reservas.add(res);
		}
		return reservas;
	}

	public String cadastraReserva(int idArea, String dataRes, String cnpj,
			String cpfAlug) {
		String sql = "INSERT INTO Reserva VALUES (" + idArea + ", '" + cpfAlug
				+ "', '" + cnpj + "', to_date('" + dataRes
				+ "', 'DD/MM/YYYY HH24'))";
		String res;
		try {
			this.comando = this.con.prepareStatement(sql);
			this.comando.executeUpdate();
			res = "OK";
		} catch (SQLException e) {
			res = "Dado existente";
		}

		System.out.println(sql);
		return res;

	}

	static public String customFormat(String value) {

		String pattern = "###.00";
		value = value.replace(",", ".");
		Double valor = new Double(value);
		DecimalFormat myFormatter = new DecimalFormat(pattern);
		String output = myFormatter.format(valor);
		output = output.replace(",", ".");
		System.out.println(value + "  " + pattern + "  " + output);

		return output;

	}

	public ArrayList<Notificacao> carregaNotificacoes(String cpfReceptor)
			throws SQLException {
		ArrayList<Notificacao> notificacoes = new ArrayList<Notificacao>();

		String sql = "SELECT n.cpf_informante, p.nome, n.data_not, n.descricao FROM Notificacao n INNER JOIN Pessoa p ON n.cpf_destinatario = '"
				+ cpfReceptor + "' AND p.cpf = n.cpf_informante";
		this.comando = this.con.prepareStatement(sql);
		ResultSet resultado = this.comando.executeQuery();
		
		while (resultado.next()) {
			Notificacao not = new Notificacao(resultado.getString(1),
					resultado.getString(2), resultado.getString(3),
					resultado.getString(4));
			notificacoes.add(not);
		}
		return notificacoes;
	}

	public ArrayList<Denuncia> carregaDenuncias(String cpfSindico)
			throws SQLException {
		ArrayList<Denuncia> denuncias = new ArrayList<Denuncia>();

		String sql = "SELECT m.numero, p.nome, d.DESCRICAO, d.DATA_DEN FROM PESSOA p INNER JOIN CONDOMINO c ON p.CPF = c.CPF_CONDOMINO AND c.CPF_SINDICO = '"
				+ cpfSindico
				+ "' INNER JOIN MORADORAPT m ON m.CPF_CONDOMINO = c.CPF_CONDOMINO INNER JOIN DENUNCIA d ON d.CPF_DENUNCIANTE = c.CPF_CONDOMINO";
		String sqlExtra = "SELECT m.numero, p.nome FROM PESSOA p INNER JOIN CONDOMINO c ON p.CPF = c.CPF_CONDOMINO AND c.CPF_SINDICO = '"
				+ cpfSindico
				+ "' INNER JOIN MORADORAPT m ON m.CPF_CONDOMINO = c.CPF_CONDOMINO INNER JOIN DENUNCIA d ON d.CPF_DENUNCIADO = c.CPF_CONDOMINO";

		this.comando = this.con.prepareStatement(sql);
		ResultSet result1 = this.comando.executeQuery();
		PreparedStatement comandoExtra = this.con.prepareStatement(sqlExtra);
		ResultSet result2 = comandoExtra.executeQuery();
		
		while (result1.next() && result2.next()) {
			Denuncia d = new Denuncia(result1.getString(1),
					result2.getString(1), result1.getString(2),
					result2.getString(2), result1.getString(3),
					result1.getString(4));
			denuncias.add(d);
		}
		
		return denuncias;
	}
	
	public void excluirMorador(String cpf) {
		System.out.println("excluindo " + cpf);
		String sql;
		sql = "DELETE FROM Pessoa WHERE cpf = '" + cpf + "'";
		try {
			comando = con.prepareStatement(sql);
			comando.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public String[] carregaDadosMorador(String cpf) throws SQLException {
		String[] dados = new String[6];

		String sql = "SELECT * FROM Pessoa WHERE CPF = '" + cpf + "'";
		this.comando = this.con.prepareStatement(sql);
		
		ResultSet resultado = this.comando.executeQuery();
		if (resultado.next()) {
			dados[0] = resultado.getString(1);
			dados[1] = resultado.getString(2);
			dados[2] = resultado.getString(3);
			dados[3] = resultado.getString(5);
			dados[4] = resultado.getString(6);
			dados[5] = resultado.getString(7);
		}
		
		System.out.println(sql);
		
		return dados;
	}

	public void updateMorador(String[] novosDados, String cpf)
			throws SQLException {
		String sql = "UPDATE PESSOA SET nome = '" + novosDados[0]
				+ "', login = '" + novosDados[1] + "', email = '"
				+ novosDados[2] + "', telefone = '" + novosDados[3]
				+ "', data_nasc = '" + novosDados[4] + "' WHERE cpf = '" + cpf
				+ "'";

		this.comando = this.con.prepareStatement(sql);
		this.comando.executeUpdate();


	}
	
	public ArrayList<Reserva> listHistorico(String cpf) throws SQLException {
		ArrayList<Reserva> reservas = new ArrayList<Reserva>();

		String sql = "SELECT r.CPF_RESPONSAVEL, p.NOME, al.NOME, r.DATA_RESERVA FROM Reserva r INNER JOIN Pessoa p ON r.CPF_RESPONSAVEL = '"+cpf+"' AND p.CPF = r.CPF_RESPONSAVEL INNER JOIN AREA_LAZER al ON r.ID = al.ID";

		this.comando = this.con.prepareStatement(sql);
		ResultSet resultado = comando.executeQuery();

		while (resultado.next()) {
			Reserva res = new Reserva(resultado.getString(1),
					resultado.getString(2), resultado.getString(3),
					resultado.getString(4));
			reservas.add(res);
		}
		return reservas;
	}

	public void fazerNotificacao(String[] dados, String cpf) {
		String sql = "INSERT INTO NOTIFICACAO (id, cpf_informante, cpf_destinatario, data_not, descricao) VALUES(seq_not.nextval, '"+cpf+"','"+dados[0]+"','"+dados[1]+"','"+dados[2]+"')";

		try {
			this.comando = this.con.prepareStatement(sql);
			this.comando.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String[] getCpfSindico(String cpf) {
		String[] sindico = new String[2];
		String sql  = "SELECT c.cpf_sindico, p.nome FROM Condomino c, Pessoa p WHERE c.cpf_condomino = '"+cpf+"' AND p.cpf = c.cpf_sindico";
		
		try {
			this.comando = this.con.prepareStatement(sql);
			ResultSet resultado = this.comando.executeQuery();
			
			if (resultado.next()) {
				sindico[0] = resultado.getString(1);
				sindico[1] = resultado.getString(2);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sindico;
	}
}